package com.jiawa.train.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jiawa.train.business.domain.TrainCarriage;
import com.jiawa.train.business.domain.TrainSeat;
import com.jiawa.train.business.domain.TrainSeatExample;
import com.jiawa.train.business.enums.SeatColEnum;
import com.jiawa.train.business.mapper.TrainSeatMapper;
import com.jiawa.train.business.req.TrainSeatQueryReq;
import com.jiawa.train.business.req.TrainSeatSaveReq;
import com.jiawa.train.business.resp.TrainSeatQueryResp;
import com.jiawa.train.business.service.TrainCarriageService;
import com.jiawa.train.business.service.TrainSeatService;
import com.jiawa.train.common.exception.BusinessException;
import com.jiawa.train.common.exception.BusinessExceptionEnum;
import com.jiawa.train.common.resp.PageResp;
import com.jiawa.train.common.util.SnowUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author zzl
 * @version 1.0
 */
@Service
public class TrainSeatServiceImpl implements TrainSeatService {
    private static final Logger LOG = LoggerFactory.getLogger(TrainSeatServiceImpl.class);

    @Resource
    private TrainSeatMapper trainSeatMapper;
    @Resource
    private TrainCarriageService trainCarriageService;

    /**
     * 新增一条高铁座位信息
     * @param req
     */
    @Override
    public void save(TrainSeatSaveReq req) {
        DateTime now = DateTime.now();
        TrainSeat trainSeat = BeanUtil.copyProperties(req, TrainSeat.class);
        if(ObjectUtil.isNull(trainSeat.getId())) {
            if(isExist(trainSeat)) {
                throw new BusinessException(BusinessExceptionEnum.TRAIN_CARRIAGE_SEAT_IS_EXIST);
            } else {
                trainSeat.setId(SnowUtil.getSnowflakeNextId());
                trainSeat.setCreateTime(now);
                trainSeat.setUpdateTime(now);
                trainSeatMapper.insert(trainSeat);
            }
        } else {
            trainSeat.setUpdateTime(now);
            trainSeatMapper.updateByPrimaryKeySelective(trainSeat);
        }
    }

    /**
     * 分页查询高铁座位信息
     * @param req
     * @return
     */
    @Override
    public PageResp<TrainSeatQueryResp> queryList(TrainSeatQueryReq req) {
        TrainSeatExample trainSeatExample = new TrainSeatExample();
        trainSeatExample.setOrderByClause("train_code asc, carriage_index asc, carriage_seat_index asc");
        TrainSeatExample.Criteria criteria = trainSeatExample.createCriteria();
        if(ObjectUtil.isNotNull(req.getTrainCode())) {
            criteria.andTrainCodeEqualTo(req.getTrainCode());
        }

        LOG.info("查询页码：{}", req.getPage());
        LOG.info("每页条数：{}", req.getSize());
        PageHelper.startPage(req.getPage(), req.getSize());
        List<TrainSeat> trainSeatList = trainSeatMapper.selectByExample(trainSeatExample);

        PageInfo<TrainSeat> pageInfo = new PageInfo<>(trainSeatList);
        LOG.info("总行数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());

        List<TrainSeatQueryResp> trainSeatQueryRespList = BeanUtil.copyToList(trainSeatList, TrainSeatQueryResp.class);
        PageResp<TrainSeatQueryResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(trainSeatQueryRespList);
        return pageResp;
    }

    /**
     * 根据id删除高铁座位信息
     * @param id
     */
    @Override
    public void delete(Long id) {
        trainSeatMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据高铁车次生成高铁座位信息
     * @param trainCode
     */
    @Transactional
    @Override
    public void genTrainSeat(String trainCode) {
        // 清空当前车次下的所有的座位记录
        TrainSeatExample trainSeatExample = new TrainSeatExample();
        trainSeatExample.createCriteria().andTrainCodeEqualTo(trainCode);
        trainSeatMapper.deleteByExample(trainSeatExample);

        // 查找当前车次下的所有的车厢
        List<TrainCarriage> trainCarriageList = trainCarriageService.selectByTrainCode(trainCode);
        LOG.info("当前车次下的车厢数：{}", trainCarriageList.size());

        DateTime now = DateTime.now();
        // 循环生成每个车厢的座位
        for(TrainCarriage trainCarriage : trainCarriageList) {
            // 拿到车厢数据：行数、座位类型(得到列数)
            Integer rowCount = trainCarriage.getRowCount();

            // 根据车厢的座位类型，筛选出所有的列，比如车箱类型是一等座，则筛选出columnList={ACDF}
            List<SeatColEnum> seatColEnumList = SeatColEnum.getColsByType(trainCarriage.getSeatType());
            LOG.info("根据车厢的座位类型，筛选出所有的列：{}", seatColEnumList);

            int seatIndex = 0;
            for(int row = 1; row <= rowCount; row++) {
                for(SeatColEnum seatColEnum : seatColEnumList) {
                    TrainSeat trainSeat = new TrainSeat();
                    trainSeat.setId(SnowUtil.getSnowflakeNextId());
                    trainSeat.setTrainCode(trainCode);
                    trainSeat.setCarriageIndex(trainCarriage.getIndex());
                    trainSeat.setRow(StrUtil.fillBefore(String.valueOf(row), '0', 2));
                    trainSeat.setCol(seatColEnum.getCode());
                    trainSeat.setSeatType(trainCarriage.getSeatType());
                    trainSeat.setCarriageSeatIndex(++seatIndex);
                    trainSeat.setCreateTime(now);
                    trainSeat.setUpdateTime(now);
                    trainSeatMapper.insert(trainSeat);
                }
            }
        }
    }

    /**
     * 根据高铁车次查询高铁座位信息
     * @param code
     * @return
     */
    @Override
    public List<TrainSeat> selectByTrainCode(String code) {
        TrainSeatExample trainSeatExample = new TrainSeatExample();
        trainSeatExample.createCriteria()
                .andTrainCodeEqualTo(code);
        return trainSeatMapper.selectByExample(trainSeatExample);
    }

    /**
     * 判断高铁座位信息是否存在
     * @param trainSeat
     * @return
     */
    private boolean isExist(TrainSeat trainSeat) {
        TrainSeatExample trainSeatExample = new TrainSeatExample();
        trainSeatExample.createCriteria()
                .andTrainCodeEqualTo(trainSeat.getSeatType())
                .andCarriageIndexEqualTo(trainSeat.getCarriageIndex())
                .andCarriageSeatIndexEqualTo(trainSeat.getCarriageSeatIndex());
        List<TrainSeat> list = trainSeatMapper.selectByExample(trainSeatExample);
        if(CollUtil.isNotEmpty(list)) return true;
        else return false;
    }

}
